package com.easy.mongodb.core.conditions.interfaces;

import com.easy.mongodb.common.utils.CollectionUtils;
import com.easy.mongodb.common.utils.ExceptionUtils;
import com.easy.mongodb.core.biz.PageInfo;
import com.easy.mongodb.core.conditions.Wrapper;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * ProductName: easy-mongodb
 * Package: com.easy.mongodb.core.conditions.interfaces
 *
 * @Description:
 * @Author: vapeshop
 * @Date: 2022/6/29 18:52
 * UpdateUser: vapeshop
 * UpdateDate: 2022/6/29 18:52
 * UpdateRemark: The modified content
 * @Version: 1.0
 * <p>
 * Copyright © 2022 vapeshop Technologies Inc. All Rights Reserved
 **/
public interface BaseMongoMapper<T> {
    /**
     * 插入一条记录
     *
     * @param entity 实体对象
     */
    Long insert(T entity);

    /**
     * 批量插入
     *
     * @param entityList 插入的数据对象列表
     * @return 总成功条数
     */
    Long insertBatch(Collection<T> entityList);

    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    Long deleteById(Serializable id);

    /**
     * 根据实体(ID)删除
     *
     * @param entity 实体对象
     * @since 3.4.4
     */
    Long deleteById(T entity);

    /**
     * 根据 columnMap 条件，删除记录
     *
     * @param columnMap 表字段 map 对象
     */
    Long deleteByMap(Map<String, Object> columnMap);

    /**
     * 根据 entity 条件，删除记录
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null,里面的 entity 用于生成 where 语句）
     */
    Long delete(Wrapper<T> queryWrapper);

    /**
     * 删除（根据ID或实体 批量删除）
     *
     * @param idList 主键ID列表或实体列表(不能为 null 以及 empty)
     */
    Long deleteBatchIds(Collection<?> idList);

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    Long updateById(T entity);

    /**
     * 根据 whereEntity 条件，更新记录
     *
     * @param entity        实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类（可以为 null,里面的 entity 用于生成 where 语句）
     */
    Long update(T entity, Wrapper<T> updateWrapper);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    T selectById(Serializable id);

    T selectById(Serializable id, boolean isCascade);

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     */
    List<T> selectBatchIds(Collection<? extends Serializable> idList);

    /**
     * 查询（根据 columnMap 条件）
     *
     * @param columnMap 表字段 map 对象
     */
    List<T> selectByMap(Map<String, Object> columnMap);

    /**
     * 根据 entity 条件，查询一条记录
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default T selectOne(Wrapper<T> queryWrapper) {
        List<T> ts = this.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(ts)) {
            if (ts.size() != 1) {
                throw ExceptionUtils.build("One record is expected, but the query result is multiple records");
            }
            return ts.get(0);
        }
        return null;
    }

    /**
     * 根据 Wrapper 条件，判断是否存在记录
     *
     * @param queryWrapper 实体对象封装操作类
     * @return 是否存在记录
     */
    default boolean exists(Wrapper<T> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0;
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    Long selectCount(Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    List<T> selectList(Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param entity 实体对象（可以为 null）
     */
    List<T> selectList(T entity);

    /**
     * 指定返回类型及分页参数
     *
     * @param wrapper  条件
     * @param pageNum  当前页
     * @param pageSize 每页条数
     * @return 指定的返回类型
     */
    PageInfo<T> page(Wrapper<T> wrapper, Integer pageNum, Integer pageSize);

    /**
     * 谨慎操作！！！
     */
    void drop();

    void insert(String collectionName, Document doc);

    MongoDatabase getMongoDatabase();
}
